package com.freecloud.javabasics.thread.lock;

import com.freecloud.common.LoggerUtil;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 读写锁
 *
 * //读 ->读是可以共享
 * //读 ->写 互斥
 * //写 ->写 互斥
 *
 * 适合读多写少的场景
 * @Author: maomao
 * @Date: 2020-02-18 09:24
 */
public class ReentrantReadWriteLockDemo {

    static ReentrantReadWriteLock wrl = new ReentrantReadWriteLock();

    static Map<String,Object> cacheMap = new HashMap<>();

    static Lock read = wrl.readLock();
    static Lock write = wrl.writeLock();

    /**
     * （2）线程B
     * @param key
     * @return
     */
    public static final Object get(String key){
        LoggerUtil.println("begin read data: %s",key);
        read.lock();//获得读锁 -> 阻塞（直到线程A执行完成）
        try {
            return cacheMap.get(key);
        }finally {
            read.unlock();
        }
    }

    /**
     * （1）线程A
     * @param key
     * @param val
     * @return
     */
    public static final Object put(String key,Object val){
        write.lock();//获得了写锁
        try {
            return cacheMap.put(key,val);
        }finally {
            write.unlock();
        }
    }

    public static void main(String[] args) {
        wrl.readLock();//（2）B线程 ->阻塞 （避免线程B获得脏数据）

        wrl.writeLock();//（1）A线程先获得写锁
    }
}
